﻿unit UMainForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.ComCtrls, Data.DB, Vcl.Grids, Vcl.DBGrids,
  System.ImageList, Vcl.ImgList, Vcl.Menus;

type
  TMainForm = class(TForm)
    pnlTop: TPanel;
    pnlLeft: TPanel;
    pnlMain: TPanel;
    tvCategories: TTreeView;
    dbgMemos: TDBGrid;
    edtSearch: TEdit;
    tmrReminder: TTimer;
    TrayIcon: TTrayIcon;
    MainMenu: TMainMenu;
    mnuFile: TMenuItem;
    mnuCategory: TMenuItem;
    mnuExit: TMenuItem;
    cbbSearchType: TComboBox;
    cbbPriorityFilter: TComboBox;
    cbbStatusFilter: TComboBox;
    chkDateRange: TCheckBox;
    dtpDateFrom: TDateTimePicker;
    dtpDateTo: TDateTimePicker;
    
    procedure FormCreate(Sender: TObject);
    procedure btnAddClick(Sender: TObject);
    procedure btnEditClick(Sender: TObject);
    procedure btnDeleteClick(Sender: TObject);
    procedure tmrReminderTimer(Sender: TObject);
    procedure edtSearchChange(Sender: TObject);
    procedure tvCategoriesChange(Sender: TObject; Node: TTreeNode);
    procedure mnuCategoryClick(Sender: TObject);
    procedure mnuExitClick(Sender: TObject);
    procedure cbbSearchTypeChange(Sender: TObject);
    procedure cbbPriorityFilterChange(Sender: TObject);
    procedure cbbStatusFilterChange(Sender: TObject);
    procedure chkDateRangeClick(Sender: TObject);
    procedure dtpDateChange(Sender: TObject);
  private
    procedure InitializeUI;
    procedure LoadCategories;
    procedure LoadMemos;
    procedure CheckReminders;
    procedure InitializeFilters;
    procedure ApplyFilters;
    function BuildFilterSQL: string;
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

uses UDataModule, UMemoEdit, UReminder, UCategoryEdit;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  InitializeUI;
  InitializeFilters;
  LoadCategories;
  LoadMemos;
  
  tmrReminder.Interval := 60000;
  tmrReminder.Enabled := True;
end;

procedure TMainForm.InitializeUI;
begin
  // 设置DBGrid的列
  with dbgMemos.Columns do
  begin
    Clear;  // 先清除所有列
    
    with Add do
    begin
      FieldName := 'Title';
      Title.Caption := '标题';
      Width := 200;
    end;
    
    with Add do
    begin
      FieldName := 'CreateTime';
      Title.Caption := '创建时间';
      Width := 150;
    end;
    
    with Add do
    begin
      FieldName := 'Priority';
      Title.Caption := '优先级';
      Width := 80;
    end;
    
    with Add do
    begin
      FieldName := 'Status';
      Title.Caption := '状态';
      Width := 80;
    end;
  end;
end;

procedure TMainForm.CheckReminders;
begin
  // 检查是否有需要提醒的事项
  with DM.qryReminder do
  begin
    Close;
    SQL.Text := 'SELECT R.*, M.Title, M.Content FROM Reminder R ' +
                'INNER JOIN Memo M ON R.MemoID = M.ID ' +
                'WHERE R.Status = 0 AND R.RemindTime <= GETDATE()';
    Open;
    
    while not EOF do
    begin
      // 显示提醒窗口
      TReminderForm.ShowReminder(
        FieldByName('Title').AsString,
        FieldByName('Content').AsString,
        FieldByName('RemindTime').AsDateTime,
        FieldByName('MemoID').AsInteger,
        FieldByName('ID').AsInteger
      );
      Next;
    end;
  end;
end;

procedure TMainForm.tmrReminderTimer(Sender: TObject);
begin
  CheckReminders;
end;

procedure TMainForm.btnAddClick(Sender: TObject);
begin
  if TMemoEditForm.EditMemo then
    LoadMemos;  // 刷新备忘录列表
end;

procedure TMainForm.btnEditClick(Sender: TObject);
begin
  if DM.dsMemo.DataSet.IsEmpty then
    Exit;
    
  if TMemoEditForm.EditMemo(DM.dsMemo.DataSet.FieldByName('ID').AsInteger) then
    LoadMemos;  // 刷新备忘录列表
end;

procedure TMainForm.mnuCategoryClick(Sender: TObject);
begin
  TCategoryEditForm.ShowCategoryManager;
  LoadCategories;  // 刷新分类树
end;

procedure TMainForm.mnuExitClick(Sender: TObject);
begin
  Close;
end;

procedure TMainForm.LoadCategories;
begin
  with tvCategories.Items do
  begin
    Clear;
    
    // 添加"全部"节点
    Add(nil, '全部');
    
    // 加载分类
    with DM.qryCategory do
    begin
      Close;
      SQL.Text := 'SELECT * FROM Category ORDER BY Name';
      Open;
      
      while not EOF do
      begin
        Add(nil, FieldByName('Name').AsString).Data := Pointer(FieldByName('ID').AsInteger);
        Next;
      end;
    end;
    
    // 选中第一个节点
    if Count > 0 then
    begin
      Items[0].Selected := True;
      tvCategoriesChange(tvCategories, Items[0]);
    end;
  end;
end;

procedure TMainForm.tvCategoriesChange(Sender: TObject; Node: TTreeNode);
begin
  if Node = nil then
    Exit;
    
  ApplyFilters;
end;

procedure TMainForm.InitializeFilters;
begin
  // 初始化搜索类型
  with cbbSearchType.Items do
  begin
    Clear;
    Add('标题');
    Add('内容');
    Add('全部');
  end;
  cbbSearchType.ItemIndex := 0;

  // 初始化优先级筛选
  with cbbPriorityFilter.Items do
  begin
    Clear;
    Add('全部优先级');
    Add('高');
    Add('中');
    Add('低');
  end;
  cbbPriorityFilter.ItemIndex := 0;

  // 初始化状态筛选
  with cbbStatusFilter.Items do
  begin
    Clear;
    Add('全部状态');
    Add('未完成');
    Add('已完成');
  end;
  cbbStatusFilter.ItemIndex := 0;

  // 初始化日期选择器
  dtpDateFrom.Date := Date - 30;  // 默认显示最近30天
  dtpDateTo.Date := Date;
  
  chkDateRange.Checked := False;
  dtpDateFrom.Enabled := False;
  dtpDateTo.Enabled := False;
end;

procedure TMainForm.ApplyFilters;
var
  SQL: string;
  CategoryID: Integer;
begin
  if tvCategories.Selected = nil then
    Exit;

  if tvCategories.Selected.Index = 0 then  // "全部"节点
    CategoryID := -1
  else
    CategoryID := Integer(tvCategories.Selected.Data);

  SQL := BuildFilterSQL;
  
  with DM.qryMemo do
  begin
    Close;
    SQL.Text := SQL;
    
    // 设置分类参数
    if CategoryID <> -1 then
      Parameters.ParamByName('CategoryID').Value := CategoryID;
      
    // 设置搜索参数
    if edtSearch.Text <> '' then
      Parameters.ParamByName('SearchText').Value := '%' + edtSearch.Text + '%';
      
    // 设置优先级参数
    if cbbPriorityFilter.ItemIndex > 0 then
      Parameters.ParamByName('Priority').Value := cbbPriorityFilter.ItemIndex;
      
    // 设置状态参数
    if cbbStatusFilter.ItemIndex > 0 then
      Parameters.ParamByName('Status').Value := cbbStatusFilter.ItemIndex - 1;
      
    // 设置日期范围参数
    if chkDateRange.Checked then
    begin
      Parameters.ParamByName('DateFrom').Value := dtpDateFrom.Date;
      Parameters.ParamByName('DateTo').Value := dtpDateTo.Date + 1;  // 包含结束日期
    end;
    
    Open;
  end;
end;

function TMainForm.BuildFilterSQL: string;
var
  WhereClause: string;
  OrderClause: string;
begin
  Result := 'SELECT * FROM Memo';
  WhereClause := '';
  OrderClause := ' ORDER BY CreateTime DESC';

  // 分类筛选
  if tvCategories.Selected.Index > 0 then
    WhereClause := WhereClause + ' CategoryID = :CategoryID';

  // 搜索条件
  if edtSearch.Text <> '' then
  begin
    if WhereClause <> '' then
      WhereClause := WhereClause + ' AND ';
      
    case cbbSearchType.ItemIndex of
      0: WhereClause := WhereClause + 'Title LIKE :SearchText';
      1: WhereClause := WhereClause + 'Content LIKE :SearchText';
      2: WhereClause := WhereClause + '(Title LIKE :SearchText OR Content LIKE :SearchText)';
    end;
  end;

  // 优先级筛选
  if cbbPriorityFilter.ItemIndex > 0 then
  begin
    if WhereClause <> '' then
      WhereClause := WhereClause + ' AND ';
    WhereClause := WhereClause + 'Priority = :Priority';
  end;

  // 状态筛选
  if cbbStatusFilter.ItemIndex > 0 then
  begin
    if WhereClause <> '' then
      WhereClause := WhereClause + ' AND ';
    WhereClause := WhereClause + 'Status = :Status';
  end;

  // 日期范围筛选
  if chkDateRange.Checked then
  begin
    if WhereClause <> '' then
      WhereClause := WhereClause + ' AND ';
    WhereClause := WhereClause + 'CreateTime >= :DateFrom AND CreateTime < :DateTo';
  end;

  if WhereClause <> '' then
    Result := Result + ' WHERE ' + WhereClause;
    
  Result := Result + OrderClause;
end;

procedure TMainForm.edtSearchChange(Sender: TObject);
begin
  ApplyFilters;
end;

procedure TMainForm.cbbSearchTypeChange(Sender: TObject);
begin
  if edtSearch.Text <> '' then
    ApplyFilters;
end;

procedure TMainForm.cbbPriorityFilterChange(Sender: TObject);
begin
  ApplyFilters;
end;

procedure TMainForm.cbbStatusFilterChange(Sender: TObject);
begin
  ApplyFilters;
end;

procedure TMainForm.chkDateRangeClick(Sender: TObject);
begin
  dtpDateFrom.Enabled := chkDateRange.Checked;
  dtpDateTo.Enabled := chkDateRange.Checked;
  ApplyFilters;
end;

procedure TMainForm.dtpDateChange(Sender: TObject);
begin
  if chkDateRange.Checked then
    ApplyFilters;
end;

end. 